<?php
require_once 'models/publisher.inc';
require_once 'models/TCMSCategoryModel.inc';
require_once 'models/TCMSCategoryModel.inc';
require_once 'models/TCMSPageModel.inc';

/**
 * @author kras
 * 
 * @property TCMSCategoryModel $CategoriesModel
 * @property TMSTypesModel $TypesModel
 * @property TCMSPageAssociationClassModel $AssociationClassesModel
 * @property IItemPublisher $Companion
 */

abstract class TCMSPublisher extends TCMSPageModel implements IItemPublisher {	
/**
 * @var TCMSCategoryModel
 */
	protected $_ioc_categories_model_;
		
/**
 * @var TMSTypesModel
 */	
	protected $_ioc_types_model_;
	
/**
 * @var IItemPublisher[]
 */	
	protected $_ioc_companion_;
	
/**
 * @var TCMSPageAssociationClassModel
 */	
	protected $_ioc_association_classes_model_;
	
	protected function autoAgregate(IItem $item, IItem $issue){
		if ($this->AssociationModel && $this->TypesModel){
			if ($t = $this->TypesModel->GetItem($item->ClassName())){
				if ($aa = $t->AgregationAttribute)			
					if ($c = $item->$aa)
						if ($c instanceof IItem){
							$cp = $c->Properties(array(TItemPropertyType::PT_COLLECTION));
							$p = false;
							foreach ($cp as $candidate){
								$cn = $candidate->ClassName();
								if (isset($candidate->FilterProperty) && ($candidate->FilterProperty == $aa) && ($item->Base instanceof $cn)
								){
									$p = $candidate;
									break;
								}					
							}	
							
							if ($p){
								if ($parent = $this->ItemIssue($c)){
									$ac = false;
									foreach ($parent->AssociationClasses as $candidate)
										if ($candidate->Name == $p->Caption()){
											$ac = $candidate;
											break;
										}
									if (!$ac){
										$acl = $this->AssociationClassesModel->GetList(new TListOptions(array(new TFilterOption('Name', TConditionType::C_EQUAL, $p->Caption()))));
										foreach ($acl as $candidate){
											$ac = $candidate;
											break;
										}
										if (!$ac)
											$ac = $this->AssociationClassesModel->CreateItem(array('Name'=>$p->Caption(),'Type'=>TMSPageAssociationType::AGREGATED));
										
										if ($ac->Type != TMSPageAssociationType::AGREGATED)
											$ac = false;		
									}
									if ($ac)
										$this->AssociationModel->AssociatePages($ac, $parent, array($issue->ItemId()));
								}
							}	
						}
			}				
		}	
	}
	
	public function OnItemDelete(IItem $item){
		if ($page = $this->ItemIssue($item))
			$this->DeleteItem($page->ItemId());
	}
	
/**
 * @param IItem $item
 * @return IItem
 */
	public function PublishItem(IItem $item,array $data){
		if ($result = $this->createIssue($item)){
			$this->initialCategoryAssignment($item,$result, $data);
			$this->autoAgregate($item, $result);
		}
		return $result;
	}
	
/**
 * @param IItem $item
 * @return IItem
 */
	public function ItemIssue(IItem $item){
		$cmp = $this->Companion;
		if ($cmp){
			if (!is_array($cmp))
				$cmp = array($cmp);
			foreach ($cmp as $c)
				if ($r = $c->ItemIssue($item))
					return $r;
		}	
		return null;
	}	
	
/**
 * @param IItem $item
 * @return IItem|boolean
 */	
	protected abstract function createIssue(IItem $item);

/**
 * 
 * @param IItem $item
 * @return IItem|boolean
 */	
	
	protected function getDPC(IItem $item){
		if ($this->ShopSettings){
			$dpc = $this->ShopSettings->GetValue('PublishRules');
			if ($dpc){
				$dpc = TConvertions::ConvertToArray($dpc,array(',','='),array(false,true));
				if (isset($dpc[$item->ClassName()])){
					$match = $this->CategoriesModel->GetList(new TListOptions(array(new TFilterOption('Slug', TConditionType::C_EQUAL, $dpc[$item->ClassName()]))));
					foreach ($match as $dpc) return $dpc;
				}
			}
		}				
		return false;		
	}
	
	protected function initialCategoryAssignment(IItem $item, IItem $page, array $data){
		$pc = new TMSCategoryPageAssociation();
		$pc->Page = $page->ItemId();
		if (empty($data)){
			if ($dpc = $this->getDPC($item)){
				$pc->Category = $dpc;
				$this->Adapter->Save($pc);
			}
		} else
			foreach ($data as $catid){
				$pc->Category = $catid;
				$this->Adapter->Save($pc);
			}		
	}

	public function Categories(){
		return $this->CategoriesModel->GetContents(null,false);
	}	
}